package symbol;

import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;


public class MethodTable {
	// Mapeia todos os identificadores aos seus tipos
	private Dictionary<Symbol,Symbol> locals; // and parameters
	// Guarda os tipos dos parâmetros em ordem
	private Vector<Symbol> paramsTypes;

	// Nome do método e seu tipo 
	private Symbol id;
	private Symbol type;
	
	
	public Symbol getId ()
	{
		return id;
	}
	
	public MethodTable( Symbol i , Symbol t ){
		locals      = new Hashtable<Symbol,Symbol>();
		paramsTypes = new Vector<Symbol>();		
		type   = t;
		id     = i;
	}
	
	public void putParams( Symbol id , Symbol type ) throws Exception{
		if(locals.get(id) != null  ){
			throw new Exception("Dupla declaracao de variaveis");
		}
		
		paramsTypes.add(type);	
		locals.put(id,type);
	}
	
	public void putLocals( Symbol id , Symbol type ) throws Exception{
		if( locals.get(id) != null  ){
			throw new Exception("Dupla declaracao de variaveis");
		}

		locals.put(id, type);	
	}	
	
	public Symbol getType(Symbol id) throws Exception{
		Symbol type = locals.get(id);		
		return type;
	}
	
	public void getParams(Vector<Symbol> ps) throws Exception{
		
		String params = new String();
		String inputs = new String();
		
		if( !ps.equals(paramsTypes) ){
			
			for( int i = 0 ; i < paramsTypes.size() ; i++ ){
				params += paramsTypes.elementAt(i).toString();
				if( i + 1 < paramsTypes.size() )
					params += ",";
			}
			
			for( int i = 0 ; i < ps.size() ; i++ ){
				inputs += ps.elementAt(i).toString();
				if( i + 1 < ps.size() )
					inputs += ",";
			}
			
			throw new Exception("Parametros incorretos, esperado: " +
					this.id.toString() +"("+params+")" + " encontrado " + 
					this.id.toString() +"("+inputs+")");
		}
	
	}
	
	public Symbol returnType(){
		return this.type;
	}
	
	
	
	public void imprimeLocals(){
		
		System.out.println("-- " + "Locais");
		
		for (Enumeration<Symbol> m=this.locals.keys(); m.hasMoreElements(); )		
			System.out.println(" ---- " + m.nextElement().toString());
						
		
	}

}
